<?php

// 公共助手函数

if (!function_exists('__')) {

    /**
     * 获取语言变量值
     * @param string $name 语言变量名
     * @param array $vars 动态变量值
     * @param string $lang 语言
     * @return mixed
     */
    function __($name, $vars = [], $lang = '')
    {
        if (is_numeric($name) || !$name)
            return $name;
        if (!is_array($vars)) {
            $vars = func_get_args();
            array_shift($vars);
            $lang = '';
        }
        return \think\Lang::get($name, $vars, $lang);
    }

}

if (!function_exists('format_bytes')) {

    /**
     * 将字节转换为可读文本
     * @param int $size 大小
     * @param string $delimiter 分隔符
     * @return string
     */
    function format_bytes($size, $delimiter = '')
    {
        $units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
        for ($i = 0; $size >= 1024 && $i < 6; $i++)
            $size /= 1024;
        return round($size, 2) . $delimiter . $units[$i];
    }

}

if (!function_exists('datetime')) {

    /**
     * 将时间戳转换为日期时间
     * @param int $time 时间戳
     * @param string $format 日期时间格式
     * @return string
     */
    function datetime($time, $format = 'Y-m-d H:i:s')
    {
        $time = is_numeric($time) ? $time : strtotime($time);
        return date($format, $time);
    }

}

if (!function_exists('human_date')) {

    /**
     * 获取语义化时间
     * @param int $time 时间
     * @param int $local 本地时间
     * @return string
     */
    function human_date($time, $local = null)
    {
        return \fast\Date::human($time, $local);
    }

}

if (!function_exists('cdnurl')) {

    /**
     * 获取上传资源的CDN的地址
     * @param string $url 资源相对地址
     * @param boolean $domain 是否显示域名 或者直接传入域名
     * @return string
     */
    function cdnurl($url, $domain = false)
    {
        $url = preg_match("/^https?:\/\/(.*)/i", $url) ? $url : \think\Config::get('upload.cdnurl') . $url;
        if ($domain && !preg_match("/^(http:\/\/|https:\/\/)/i", $url)) {
            if (is_bool($domain)) {
                $public = \think\Config::get('view_replace_str.__PUBLIC__');
                $url = rtrim($public, '/') . $url;
                if (!preg_match("/^(http:\/\/|https:\/\/)/i", $url)) {
                    $url = request()->domain() . $url;
                }
            } else {
                $url = $domain . $url;
            }
        }
        return $url;
    }

}


if (!function_exists('is_really_writable')) {

    /**
     * 判断文件或文件夹是否可写
     * @param    string $file 文件或目录
     * @return    bool
     */
    function is_really_writable($file)
    {
        if (DIRECTORY_SEPARATOR === '/') {
            return is_writable($file);
        }
        if (is_dir($file)) {
            $file = rtrim($file, '/') . '/' . md5(mt_rand());
            if (($fp = @fopen($file, 'ab')) === FALSE) {
                return FALSE;
            }
            fclose($fp);
            @chmod($file, 0777);
            @unlink($file);
            return TRUE;
        } elseif (!is_file($file) OR ($fp = @fopen($file, 'ab')) === FALSE) {
            return FALSE;
        }
        fclose($fp);
        return TRUE;
    }

}

if (!function_exists('rmdirs')) {

    /**
     * 删除文件夹
     * @param string $dirname 目录
     * @param bool $withself 是否删除自身
     * @return boolean
     */
    function rmdirs($dirname, $withself = true)
    {
        if (!is_dir($dirname))
            return false;
        $files = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($dirname, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST
        );

        foreach ($files as $fileinfo) {
            $todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
            $todo($fileinfo->getRealPath());
        }
        if ($withself) {
            @rmdir($dirname);
        }
        return true;
    }

}

if (!function_exists('copydirs')) {

    /**
     * 复制文件夹
     * @param string $source 源文件夹
     * @param string $dest 目标文件夹
     */
    function copydirs($source, $dest)
    {
        if (!is_dir($dest)) {
            mkdir($dest, 0755, true);
        }
        foreach (
            $iterator = new RecursiveIteratorIterator(
                new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST) as $item
        ) {
            if ($item->isDir()) {
                $sontDir = $dest . DS . $iterator->getSubPathName();
                if (!is_dir($sontDir)) {
                    mkdir($sontDir, 0755, true);
                }
            } else {
                copy($item, $dest . DS . $iterator->getSubPathName());
            }
        }
    }

}

if (!function_exists('mb_ucfirst')) {

    function mb_ucfirst($string)
    {
        return mb_strtoupper(mb_substr($string, 0, 1)) . mb_strtolower(mb_substr($string, 1));
    }

}

if (!function_exists('addtion')) {

    /**
     * 附加关联字段数据
     * @param array $items 数据列表
     * @param mixed $fields 渲染的来源字段
     * @return array
     */
    function addtion($items, $fields)
    {
        if (!$items || !$fields)
            return $items;
        $fieldsArr = [];
        if (!is_array($fields)) {
            $arr = explode(',', $fields);
            foreach ($arr as $k => $v) {
                $fieldsArr[$v] = ['field' => $v];
            }
        } else {
            foreach ($fields as $k => $v) {
                if (is_array($v)) {
                    $v['field'] = isset($v['field']) ? $v['field'] : $k;
                } else {
                    $v = ['field' => $v];
                }
                $fieldsArr[$v['field']] = $v;
            }
        }
        foreach ($fieldsArr as $k => &$v) {
            $v = is_array($v) ? $v : ['field' => $v];
            $v['display'] = isset($v['display']) ? $v['display'] : str_replace(['_ids', '_id'], ['_names', '_name'], $v['field']);
            $v['primary'] = isset($v['primary']) ? $v['primary'] : '';
            $v['column'] = isset($v['column']) ? $v['column'] : 'name';
            $v['model'] = isset($v['model']) ? $v['model'] : '';
            $v['table'] = isset($v['table']) ? $v['table'] : '';
            $v['name'] = isset($v['name']) ? $v['name'] : str_replace(['_ids', '_id'], '', $v['field']);
        }
        unset($v);
        $ids = [];
        $fields = array_keys($fieldsArr);
        foreach ($items as $k => $v) {
            foreach ($fields as $m => $n) {
                if (isset($v[$n])) {
                    $ids[$n] = array_merge(isset($ids[$n]) && is_array($ids[$n]) ? $ids[$n] : [], explode(',', $v[$n]));
                }
            }
        }
        $result = [];
        foreach ($fieldsArr as $k => $v) {
            if ($v['model']) {
                $model = new $v['model'];
            } else {
                $model = $v['name'] ? \think\Db::name($v['name']) : \think\Db::table($v['table']);
            }
            $primary = $v['primary'] ? $v['primary'] : $model->getPk();
            $result[$v['field']] = $model->where($primary, 'in', $ids[$v['field']])->column("{$primary},{$v['column']}");
        }

        foreach ($items as $k => &$v) {
            foreach ($fields as $m => $n) {
                if (isset($v[$n])) {
                    $curr = array_flip(explode(',', $v[$n]));

                    $v[$fieldsArr[$n]['display']] = implode(',', array_intersect_key($result[$n], $curr));
                }
            }
        }
        return $items;
    }

}

if (!function_exists('var_export_short')) {

    /**
     * 返回打印数组结构
     * @param string $var 数组
     * @param string $indent 缩进字符
     * @return string
     */
    function var_export_short($var, $indent = "")
    {
        switch (gettype($var)) {
            case "string":
                return '"' . addcslashes($var, "\\\$\"\r\n\t\v\f") . '"';
            case "array":
                $indexed = array_keys($var) === range(0, count($var) - 1);
                $r = [];
                foreach ($var as $key => $value) {
                    $r[] = "$indent    "
                        . ($indexed ? "" : var_export_short($key) . " => ")
                        . var_export_short($value, "$indent    ");
                }
                return "[\n" . implode(",\n", $r) . "\n" . $indent . "]";
            case "boolean":
                return $var ? "TRUE" : "FALSE";
            default:
                return var_export($var, TRUE);
        }
    }

}

/**
 * @param $id
 * @return mixed|string
 * 获取地区名称
 */
function get_areaname($id){
    if(!$id) return '';
    $name = db('area')->where('id',$id)->value('name');
    return $name;
}

/**
 * @param $user
 * 获取服务商的子类
 */
function my_uids($user){

}

//发布时间提示
function get_last_time($time) {
    $time = (int) substr($time, 0, 10);
    $int = time() - $time;
    $str = '';
    if ($int <= 2){
        $str = sprintf('刚刚', $int);
    }elseif ($int < 60){
        $str = sprintf('%d秒前', $int);
    }elseif ($int < 3600){
        $str = sprintf('%d分钟前', floor($int / 60));
    }elseif ($int < 86400){
        $str = sprintf('%d小时前', floor($int / 3600));
    }elseif ($int < 2592000){
        $str = sprintf('%d天前', floor($int / 86400));
    }else{
        $str = date('Y-m-d H:i:s', $time);
    }
    return $str;
}
/**
 *
 * @param  $latitude    纬度
 * @param  $longitude    经度
 * @param  $raidus        半径范围(单位：米)
 * @return multitype:number
 */
function getAround($latitude,$longitude,$raidus){
    $PI = 3.14159265;
    $degree = (24901*1609)/360.0;
    $dpmLat = 1/$degree;
    $radiusLat = $dpmLat*$raidus;
    $minLat = $latitude - $radiusLat;
    $maxLat = $latitude + $radiusLat;
    $mpdLng = $degree*cos($latitude * ($PI/180));
    $dpmLng = 1 / $mpdLng;
    $radiusLng = $dpmLng*$raidus;
    $minLng = $longitude - $radiusLng;
    $maxLng = $longitude + $radiusLng;
    return array ('minLat'=>$minLat, 'maxLat'=>$maxLat, 'minLng'=>$minLng, 'maxLng'=>$maxLng);
}

/**
 * 邀请验码-唯一不重复
 *
 * @return string
 */
function initcode() {
    $code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
    $rand = $code[rand(0,25)]
        .strtoupper(dechex(date('m')))
        .date('d').substr(time(),-5)
        .substr(microtime(),2,5)
        .sprintf('%02d',rand(0,99));
    for(
        $a = md5( $rand, true ),
        $s = '0123456789ABCDEFGHIJKLMNOPQRSTUV',
        $d = '',
        $f = 0;
        $f < 5;
        $g = ord( $a[ $f ] ),
        $d .= $s[ ( $g ^ ord( $a[ $f + 8 ] ) ) - $g & 0x1F ],
        $f++
    );
    return $d;
}

/**
 * @param $lat1
 * @param $lng1
 * @param $lat2
 * @param $lng2
 * @return int
 */
function web_getDistance($lat1, $lng1, $lat2, $lng2){


    $radLat1 = deg2rad($lat1);
    $radLat2 = deg2rad($lat2);
    $radLng1 = deg2rad($lng1);
    $radLng2 = deg2rad($lng2);
    $a = $radLat1 - $radLat2;
    $b = $radLng1 - $radLng2;
    $s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2))) * 6378.137;
    return round($s,2);

}

/**
 * 根据IP获取经纬度
 *
 * @param null $ip 当前ip
 * @return mixed
 */
function get_location_ByIP($ip=null)
{
    if(empty($ip)) $ip= request()->ip();

    //debug
    if($ip == '127.0.0.1') $ip = '116.25.225.180';

    if( cookie( 'cache_ip_location' )){
        return cookie( 'cache_ip_location' );
    }else{
        $content = file_get_contents("http://api.map.baidu.com/location/ip?ak=kYermFA2vFEkaf6CPgFoAv2ml5cFe0t2&ip=".$ip."&coor=bd09ll");
        $arr = json_decode($content,1);
        cookie( 'cache_ip_location' ,$arr);
        return $arr;

    }

}

function get_location_city($city = null){
    //默认为深圳市
    if(!$city) $city = '深圳市';
    $area = db('area')->where('name',$city)->find();
    return $area;
}

/**
 * 获取当前城市经纬度
 *
 * @return array|mixed
 */
function get_location_form(){
    if(cookie('cache_location_city')){
        return cookie('cache_location_city');
    }else{
        if( cookie( 'cache_ip_location' )){
            if(!empty(cookie( 'cache_ip_location' )['content'])){
                $point=cookie( 'cache_ip_location' )['content']['point'];
                $location=$point['y'].','.$point['x'];
            }
        }else{
            get_location_ByIP();
            $point=cookie( 'cache_ip_location' )['content']['point'];
            $location=$point['y'].','.$point['x'];
        }
        if(!empty($location)){
            $content = file_get_contents("http://api.map.baidu.com/geocoder/v2/?callback=renderReverse&location=".$location."&output=json&pois=1&latest_admin=1&ak=kYermFA2vFEkaf6CPgFoAv2ml5cFe0t2");
            $content=substr($content,29,-1);
            $arr = json_decode($content,1);
            $cache_location_city=$arr['result']['addressComponent'];
            $city['province']=$cache_location_city['province'];
            $city['city']=$cache_location_city['city'];
            $city['district']=$cache_location_city['district'];
            cookie( 'cache_location_city' ,$city);
        }else{
            $arr=array();
        }
        return $arr;
    }
}

/**
 * 通过经纬度得到位置
 *
 * @param null $location 经纬度
 * @return array
 */
function getCityList($location=null){
   try{
       $content = file_get_contents("http://api.map.baidu.com/geocoder/v2/?callback=renderReverse&location=".$location."&output=json&pois=1&latest_admin=1&ak=kYermFA2vFEkaf6CPgFoAv2ml5cFe0t2");
       $content=substr($content,29,-1);
       $arr = json_decode($content,1);

       if($arr['status']==0){
           $cache_location_city=$arr['result']['addressComponent'];
           $city['province']=$cache_location_city['province'];
           $city['city']=$cache_location_city['city'];
           $city['district']=$cache_location_city['district'];
       }else{
           $city['province']=0;
           $city['city']=0;
           $city['district']=0;
       }

   }catch (\Exception $e){
       $city=[];
   }
   return $city;
}

/**
 * 对银行卡号进行掩码处理
 * @param  string $bankCardNo 银行卡号
 * @return string             掩码后的银行卡号
 */
function formatBankCardNo($bankCardNo){
    $suffix = substr($bankCardNo,-4,4);
    $maskBankCardNo = " **** **** **** ".$suffix;
    return $maskBankCardNo;
}

function getBrankName($bank){
    $where=array('id'=>$bank);
    return db('banking')->where($where)->value('name');
}



/**
 * @param $city 要处理的城市数据
 * @param int $pid
 */
function city_merge($city,$pid=0){
    $arr = array();
    foreach ($city as $k=>$v){
        if($v['pid']==$pid){
            $v['child'] = city_merge($city,$v['id']);
            $arr[]=$v;
        }
    }
    return $arr;
}

function check_username($username){
    if (\think\Validate::regex($username, "^1\d{10}$")) {
        return substr($username,0,3).'****'.substr($username,7,4);
    }
    return $username;
}

/**
 * 获取某年第几周的开始日期和结束日期
 * @param int $year
 * @param int $week 第几周;
 */
function weekday($year,$week=1){
    $year_start = mktime(0,0,0,1,1,$year);
    $year_end = mktime(0,0,0,12,31,$year);

    // 判断第一天是否为第一周的开始
    if (intval(date('W',$year_start))===1){
        $start = $year_start;//把第一天做为第一周的开始
    }else{
        $week++;
        $start = strtotime('+1 monday',$year_start);//把第一个周一作为开始
    }

    // 第几周的开始时间
    if ($week===1){
        $weekday['start'] = $start;
    }else{
        $weekday['start'] = strtotime('+'.($week-0).' monday',$start);
    }

    // 第几周的结束时间
    $weekday['end'] = strtotime('+1 sunday',$weekday['start']);
    if (date('Y',$weekday['end'])!=$year){
        $weekday['end'] = $year_end;
    }
    return $weekday;
}

/**
 * 计算一年有多少周，每周从星期一开始，
 * 如果最后一天在周四后（包括周四）算完整的一周，否则不计入当年的最后一周
 * 如果第一天在周四前（包括周四）算完整的一周，否则不计入当年的第一周
 * @param int $year
 * return int
 */
function week($year){
    $year_start = mktime(0,0,0,1,1,$year);
    $year_end = mktime(0,0,0,12,31,$year);
    if (intval(date('W',$year_end))===1){
        return date('W',strtotime('last week',$year_end));
    }else{
        return date('W',$year_end);
    }
}

/**
 * 获取某年月的开始时间和结束时间
 * 返回数组start开始时间戳/end结束时间戳
 */
function monthday($year,$month=1){
    $monthday['start']=mktime(0,0,0,$month,1,$year);
    $monthday['end']=mktime(23,59,59,$month,date('t'),$year);
    return $monthday;
}

/**
 * xss安全过滤函数
 *
 * @param $string
 * @return string
 */
function remove_xss($string) {
    $string = preg_replace('/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S', '', $string);

    $parm1 = Array('javascript', 'vbscript', 'expression', 'applet', 'meta', 'xml', 'blink', 'link', 'script', 'embed', 'object', 'iframe', 'frame', 'frameset', 'ilayer', 'layer', 'bgsound', 'title', 'base');

    $parm2 = Array('onabort', 'onactivate', 'onafterprint', 'onafterupdate', 'onbeforeactivate', 'onbeforecopy', 'onbeforecut', 'onbeforedeactivate', 'onbeforeeditfocus', 'onbeforepaste', 'onbeforeprint', 'onbeforeunload', 'onbeforeupdate', 'onblur', 'onbounce', 'oncellchange', 'onchange', 'onclick', 'oncontextmenu', 'oncontrolselect', 'oncopy', 'oncut', 'ondataavailable', 'ondatasetchanged', 'ondatasetcomplete', 'ondblclick', 'ondeactivate', 'ondrag', 'ondragend', 'ondragenter', 'ondragleave', 'ondragover', 'ondragstart', 'ondrop', 'onerror', 'onerrorupdate', 'onfilterchange', 'onfinish', 'onfocus', 'onfocusin', 'onfocusout', 'onhelp', 'onkeydown', 'onkeypress', 'onkeyup', 'onlayoutcomplete', 'onload', 'onlosecapture', 'onmousedown', 'onmouseenter', 'onmouseleave', 'onmousemove', 'onmouseout', 'onmouseover', 'onmouseup', 'onmousewheel', 'onmove', 'onmoveend', 'onmovestart', 'onpaste', 'onpropertychange', 'onreadystatechange', 'onreset', 'onresize', 'onresizeend', 'onresizestart', 'onrowenter', 'onrowexit', 'onrowsdelete', 'onrowsinserted', 'onscroll', 'onselect', 'onselectionchange', 'onselectstart', 'onstart', 'onstop', 'onsubmit', 'onunload');

    $parm = array_merge($parm1, $parm2);

    for ($i = 0; $i < sizeof($parm); $i++) {
        $pattern = '/';
        for ($j = 0; $j < strlen($parm[$i]); $j++) {
            if ($j > 0) {
                $pattern .= '(';
                $pattern .= '(&#[x|X]0([9][a][b]);?)?';
                $pattern .= '|(&#0([9][10][13]);?)?';
                $pattern .= ')?';
            }
            $pattern .= $parm[$i][$j];
        }
        $pattern .= '/i';
        $string = preg_replace($pattern, ' ', $string);
    }
    return $string;
}

/**
 * 过滤sql防注入
 * @param $str 传入要过滤值
 * @return null|string|string[]
 */
function filterWords(&$str)
{
    $farr = array(
        "/<(\\/?)(script|i?frame|style|html|body|title|link|meta|object|\\?|\\%)([^>]*?)>/isU",
        "/(<[^>]*)on[a-zA-Z]+\s*=([^>]*>)/isU",
        "/select\b|insert\b|update\b|delete\b|drop\b|;|\"|\'|\/\*|\*|\.\.\/|\.\/|union|into|load_file|outfile|dump/is"
    );
    $str = preg_replace($farr,'',$str);
    $str = strip_tags($str);
    return $str;
}

//过滤所有html标签的属性的正则表达式
function clearHtml($content){
    return str_replace("/<([a-zA-Z]+)[^>]*>/","<\\1>",$content);
}
